<!--
 * @Description: 数字滚动组件
 * @Author: Caroline
 * @Date: 2023-11-13 15:58:39
 * @LastEditTime: 2024-02-24 22:48:49
 * @LastEditors: Caroline
 * @FilePath: \ronghe-web\src\components\count-to\index.vue
-->
<template>
  <div class="number-animation" :class="customClass">
    {{ currentValue }}
  </div>
</template>

<script setup>
import { ref, onMounted, defineProps, onUnmounted, watch } from "vue";

const props = defineProps({
  targetValue: {
    type: Number,
    required: true
  },
  duration: {
    type: Number,
    default: 800
  },
  delay: {
    type: Number,
    default: 200
  },
  customClass: {
    type: String,
    default: ""
  }
});
const timer = ref(null);
const currentValue = ref(0);
const startAnimation = () => {
  const { targetValue, duration } = props;
  const startTime = performance.now();
  const endTime = startTime + duration;
  const animate = () => {
    const now = performance.now();
    const progress = Math.min((now - startTime) / duration, 1);
    const value = Math.round(targetValue * progress);
    currentValue.value = value;

    if (now < endTime) {
      requestAnimationFrame(animate);
    }
  };
  requestAnimationFrame(animate);
};

onMounted(() => {
  timer.value = setTimeout(startAnimation, props.delay);
});

watch(
  () => props.targetValue,
  () => {
    clearTimeout(timer.value);
    timer.value = setTimeout(startAnimation, props.delay);
  }
);

onUnmounted(() => {
  clearTimeout(timer.value);
});
</script>

<style scoped>
.number-animation {
  font-size: 30px;
  font-weight: bold;
  color: #000000d9;
  line-height: 30px;
  transition: 0.3s;
}
</style>
